package lock

import (
	"context"
	"time"

	"gitee.com/shoyer/logger"
	"github.com/redis/go-redis/v9"
)

var (
	config  *Config
	lockKey = "___REDIS_LOCK_KEY___"
)

type Config struct {
	Client *redis.Client
}

func Init(c *Config) error {
	config = c
	return nil
}

func checkConfig() {
	if config == nil {
		logger.Fatalf("lock config not ok, pls check!!!")
	}
}

// Lock Lock
// Usage:
//
//	  keys := key.GetKey(key.Lock, fmt.Sprintf("BizKey-%s-%s", day.GetDate(), app.ProcessName))
//
//		if !lock.Lock(keys, time.Minute) {
//			logger.Warnf("未获取到并发锁, %s", keys)
//			return
//		}
//		defer lock.UnLock(keys)
func Lock(key string, expire time.Duration) bool {
	checkConfig()
	isSet, err := config.Client.SetNX(context.Background(), getLockKey(key), true, expire).Result()
	if err != nil {
		logger.Errorf("lock failed: %s", err.Error())
	}

	return isSet
}

// TryLock 支持重试的锁
func TryLock(key string, expire, interval time.Duration, tryTimes int) bool {
	for counter := tryTimes; counter >= 0; counter-- {
		if Lock(key, expire) {
			return true
		} else {
			time.Sleep(interval)
		}
	}

	return false
}

// UnLock alias of ReleaseLock
func UnLock(key string) {
	checkConfig()
	config.Client.Del(context.Background(), getLockKey(key))
}

func getLockKey(key string) string {
	return lockKey + key
}
